package dryworks.jsf.examples.generator;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import dryworks.examples.create.model.CreateExampleTask;
import dryworks.jsf.examples.model.SiteForExamples;

public class SiteGenerator {
	SiteForExamples siteForExamples;

	File rootProjectFolder;

	List<CreateExampleTask> examplesList;

	public void visitDirStructure(File dir, IFileFisitor []fileVisitors, String extention) {
		if (dir.isDirectory()) {
			File []files = dir.listFiles();
			for (int i = 0; i < files.length; i++) {
				visitDirStructure(files[i], fileVisitors, extention);
			}
		} else {
			for (int i = 0; i < fileVisitors.length; i++) {
				fileVisitors[i].setFile(dir);
				fileVisitors[i].actionOnFile();
			}
		}
	}
	
	public void generateAll() {
		generateMenu();
		generateExamples();
		generateConfigurationsFiles();
	}

	private void generateConfigurationsFiles() {
		generateMainFacesConfigFile();
		generateFacesConfigSubFiles();

	}

	private void generateFacesConfigSubFiles() {
		for (CreateExampleTask createExampleTask : getExamplesList()) {
			ExampleGenerator exampleGenerator = new ExampleGenerator(
					createExampleTask);
			String facesConfigSubFileContent = exampleGenerator
					.generateManagedBeanDefinition();
			String fileName = exampleGenerator
					.calculateFileNameForFacesConfigSubFile();

			File webContent = new File(getRootProjectFolder(), "WebContent");

			File folderWEBINF = new File(webContent, "WEB-INF");
			File folderForFacesConfigFiles = GeneratorFileUtils.getFolder(
					folderWEBINF, getSiteForExamples()
							.getExamplesFacesConfigFilesFolderName());

			try {
				GeneratorFileUtils.setFileContent(folderForFacesConfigFiles,
						fileName, facesConfigSubFileContent, false);
			} catch (IOException e) {
				System.err.println("faild to write file:" + fileName);
			}
		}
	}

	private void generateMainFacesConfigFile() {
		String facesConfigFileContent = generateMainFacesConfigFileContent();
		String fileName = "faces-config.xml";

		File webContent = new File(getRootProjectFolder(), "WebContent");

		File folderWEBINF = new File(webContent, "WEB-INF");
		try {
			GeneratorFileUtils.setFileContent(folderWEBINF, fileName,
					facesConfigFileContent, true);
		} catch (IOException e) {
			System.err.println("failed to write file:" + fileName);
		}
	}

	public void setResourceFileFileContent(File sourcefolder,
			String resourceBundleFullName, String content,
			List<String> languages, boolean ovewriteExisting)
			throws IOException {
		String[] fragments = resourceBundleFullName.split("\\.");

		File currentFolder = sourcefolder;
		// run on all exept last, last is the resource 'main' name
		for (int i = 0; i < fragments.length - 1; i++) {
			String fragment = fragments[i];
			currentFolder = GeneratorFileUtils.getFolder(currentFolder,
					fragment);
		}

		String fileForBundle = fragments[fragments.length - 1];
		for (String language : languages) {
			String fileForBundleWithLanguage = null;
			if (language != null && language.trim().length() > 0) {
				fileForBundleWithLanguage = fileForBundle + "_" + language
						+ ".properties";
			} else {
				fileForBundleWithLanguage = fileForBundle + ".properties";
			}

			GeneratorFileUtils.setFileContent(currentFolder,
					fileForBundleWithLanguage, content, ovewriteExisting);
		}

	}

	public void setJavaClassFileContent(File sourcefolder, String className,
			String content, boolean ovewriteExisting) throws IOException {
		String[] fragments = className.split("\\.");

		File currentFolder = sourcefolder;
		// run on all exept last, last is the file for java
		for (int i = 0; i < fragments.length - 1; i++) {
			String fragment = fragments[i];
			currentFolder = GeneratorFileUtils.getFolder(currentFolder,
					fragment);
		}

		String fileForJava = fragments[fragments.length - 1] + ".java";
		GeneratorFileUtils.setFileContent(currentFolder, fileForJava, content,
				ovewriteExisting);
	}

	private String generateMainFacesConfigFileContent() {
		StringBuffer mainFacesConfigContent = new StringBuffer();

		mainFacesConfigContent
				.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n");

		mainFacesConfigContent.append("<!DOCTYPE faces-config  [\n");
		mainFacesConfigContent
				.append("<!ENTITY userDefined SYSTEM \"faces-config-user-defined.xm1\">\n");
		mainFacesConfigContent
				.append("<!ENTITY librarySpecific SYSTEM \"faces-config-library-specific.xm1\">\n");

		mainFacesConfigContent.append("\n");
		for (CreateExampleTask createExampleTask : getExamplesList()) {
			ExampleGenerator exampleGenerator = new ExampleGenerator(
					createExampleTask);

			mainFacesConfigContent.append("<!ENTITY "
					+ exampleGenerator
							.calculateEntityNameForFacesConfigSubFile()
					+ " SYSTEM \""
					+ getSiteForExamples()
							.getExamplesFacesConfigFilesFolderName() + "/"
					+ exampleGenerator.calculateFileNameForFacesConfigSubFile()
					+ "\">\n");
		}
		mainFacesConfigContent.append("]>\n\n");
		mainFacesConfigContent.append("<faces-config>\n");
		mainFacesConfigContent.append("&userDefined;\n");
		mainFacesConfigContent.append("&librarySpecific;\n");
		for (CreateExampleTask createExampleTask : getExamplesList()) {
			ExampleGenerator exampleGenerator = new ExampleGenerator(
					createExampleTask);
			mainFacesConfigContent
					.append("&"
							+ exampleGenerator
									.calculateEntityNameForFacesConfigSubFile()
							+ ";\n");
		}
		mainFacesConfigContent.append("</faces-config>");
		return mainFacesConfigContent.toString();
	}

	private void generateExamples() {
		for (CreateExampleTask createExampleTask : getExamplesList()) {
			ExampleGenerator exampleGenerator = new ExampleGenerator(
					createExampleTask);

			// generate resource bundle
			File resourcesFolder = GeneratorFileUtils.getFolder(
					getRootProjectFolder(), getSiteForExamples()
							.getResourcesFolderName());
			String resourceFileFullMainName = exampleGenerator
					.calculateResourceBundleFullMainName();
			String resourceBundleContent = exampleGenerator
					.generateResourceBundleContent();
			List<String> supportedDefaultLanguages = getSiteForExamples()
					.getLanguages();
			try {
				setResourceFileFileContent(resourcesFolder,
						resourceFileFullMainName, resourceBundleContent,
						supportedDefaultLanguages, false);
				
				List<String> additionalExamplesNames = createExampleTask.getAdditionalExamplesNames();
				for (String additionalExampleName : additionalExamplesNames) {
					String resourceFileName = exampleGenerator
					.calculateResourceBundleFullMainName(additionalExampleName);
					setResourceFileFileContent(resourcesFolder,
							resourceFileName, resourceBundleContent,
							supportedDefaultLanguages, false);
				}
			} catch (IOException e) {
				System.err.println("cant create resource bundle:"
						+ resourceFileFullMainName + " e:" + e);
			}

			
			// generate managed bean if needed
			if (createExampleTask.isNeedManagedBean()) {
				String managedBeanFullClassName = exampleGenerator
						.calculateManagedBeanFullClassName();
				String contentOfManagedBean = exampleGenerator
						.generateManagedBeanContent();

				String sourceFolderName = getSiteForExamples()
						.getJavaSourceFolderForExamplesManagedBeanName();
				File sourceFolder = GeneratorFileUtils.getFolder(
						getRootProjectFolder(), sourceFolderName);

				try {
					setJavaClassFileContent(sourceFolder,
							managedBeanFullClassName, contentOfManagedBean,
							false);
				} catch (IOException e) {
					System.err.println("cant create managed bean:"
							+ managedBeanFullClassName + " e:" + e);
				}
			}

			// generate jspx pages
			String folderForJspsName = createExampleTask.getName();
			File webContent = new File(getRootProjectFolder(), "WebContent");

			File folderForExamples = GeneratorFileUtils.getFolder(webContent,
					createExampleTask.getCategory());
			folderForExamples = GeneratorFileUtils.getFolder(folderForExamples,
					folderForJspsName);

			String contentOfJsp = exampleGenerator
					.generateJspContentForElementOnly();

			String fileNameForSimpleExample = GeneratorStringUtils.upFirstLetter(createExampleTask
							.getName()) + ".jspx";
			try {
				GeneratorFileUtils.setFileContent(folderForExamples,
						fileNameForSimpleExample, contentOfJsp, false);
			} catch (IOException e) {
				System.err.println("cant create jsp:"
						+ fileNameForSimpleExample + " e:" + e);
			}

			List<String> additionalExamplesNames = createExampleTask
					.getAdditionalExamplesNames();
			for (String additionalExamplesName : additionalExamplesNames) {
				String fileNameForAdditionalExample = additionalExamplesName
						+ ".jspx";
				try {
					GeneratorFileUtils.setFileContent(folderForExamples,
							fileNameForAdditionalExample, contentOfJsp, false);
				} catch (IOException e) {
					System.err.println("cant create jsp:"
							+ fileNameForAdditionalExample + " e:" + e);
				}
			}
		}
	}

	private void generateMenu() {
		// generate faces-config.xml

	}

	public List<CreateExampleTask> getExamplesList() {
		if (examplesList == null) {
			examplesList = new ArrayList<CreateExampleTask>();
		}
		return examplesList;
	}

	public void setExamplesList(List<CreateExampleTask> examplesList) {
		this.examplesList = examplesList;
	}

	public SiteForExamples getSiteForExamples() {
		if (siteForExamples == null) {
			siteForExamples = new SiteForExamples();
		}
		return siteForExamples;
	}

	public void setSiteForExamples(SiteForExamples siteForExamples) {
		this.siteForExamples = siteForExamples;
	}

	public File getRootProjectFolder() {
		return rootProjectFolder;
	}

	public void setRootProjectFolder(File rootProjectFolder) {
		this.rootProjectFolder = rootProjectFolder;
	}
}
